#pragma once

/* 参考大佬们C宏元编程技巧 */
/*
    list/map/fold   https://github.com/mcinglis/macrofun
    (卧槽??)        https://github.com/Hirrolot/metalang99
*/

#include <base/base_pp.h>

/* 宏函数式编程相关 */
/* 递归求值 */
#include <base/macro/aeval.h>
/* 简单的log */
#include <base/macro/log.h>
/* 宏if */
#include <base/macro/bool.h>
/* byte运算定义 */
#include <base/macro/byte.h>
#include <base/macro/char.h>
/* if,等repeat定义 */
#include <base/macro/control.h>
/* 检测宏定义 */
#include <base/macro/detect.h>
/* fold 定义 */
#include <base/macro/fold.h>
/* map定义 */
#include <base/macro/map.h>
/* mlist定义 */
#include <base/macro/mlist.h>
/* nat定义 */
#include <base/macro/natbyte.h>


/* 列表连接, 通过FOLDL组合MCAT实现 */
#define MCAT(...)		FOLDL(__MCAT, __VA_ARGS__)

/* 如果EVAL不出来会停机报错(递归最多245次,不会溢出回绕) */
#define __ARGC_(cnt, _)		INC8(cnt)
#define ARGC_SAFE(...)		EVAL(EVAL(EVAL(FOLDL(__ARGC_, 0, __VA_ARGS__)))) /* 多eval几次 */

/* 允许溢出的BIT */
#define BIT_OVF(x)		MIF_ELSE(EQ8(x, WORD_WIDTH), 0, BIT(x))
/* 递归对比大小, 每次y减1 */
/*  le8(x, y): (1)x等于0时小于等于一切y, 返回1
    (2)x>0, y=0, 此时一定不成立, 返回0
    (3)x>0, y>0, x = y 成立, 返回1
    (4)x>0, y>0, x != y, 此时递归执行le8(x, y - 1) */
/* #define __DEFER(...)                __VA_ARGS__ __EMPTY()
 #define __REC_LE(x, y)              __MIF_ELSE(EQ8(y, 0))(0,              \
                                                 __MIF_ELSE(EQ8(x, y)) (1,      \
                                                     __DEFER(__REC_LE1)() (x, DEC8(y)))  \
                                                 )*/


// #define __REC_LE1()                 __REC_LE

// #define _REC_LE(x, y)               EVAL(__REC_LE(x, y))

// #define LE8(x, y)                   EVAL(__REC_LE(x, y))

/* 自定义函数参数 */
#define __FUNC_ARGLIST(x)	unsigned long arg##x
#define FUNC_ARGLIST(n)		MAPC(__FUNC_ARGLIST, RANGE8(n))

#define __FUNC_USEARGLIST(x)	arg##x
#define FUNC_USELIST(n)		MAPC(__FUNC_USEARGLIST, RANGE8(n))



